package cn.shanke.torrentmanagerserver.util;

import cn.shanke.torrentmanagerserver.btclient.BtClients;
import cn.shanke.torrentmanagerserver.config.AppConfig;
import cn.shanke.torrentmanagerserver.model.Client;
import cn.shanke.torrentmanagerserver.model.Config;
import cn.shanke.torrentmanagerserver.service.ClientService;
import cn.shanke.torrentmanagerserver.service.ConfigService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@Component
public class ApplicationRunnerImpl implements ApplicationRunner {

    private final Logger logger = LoggerFactory.getLogger(ApplicationRunnerImpl.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Resource
    private AppConfig appConfig;
    @Resource
    private ClientService clientService;
    @Resource
    private ConfigService configService;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        // 检查数据库文件
        String location = appConfig.getLocation();
        Path dbfile = Paths.get(location, "torrentmanager.sqlite");
        if (!Files.exists(dbfile)) {
            logger.info("db file is not exists!");
            if (!Files.exists(dbfile.getParent())) {
                Files.createDirectories(dbfile.getParent());
            }
            Files.copy(
                Thread.currentThread().getContextClassLoader().getResourceAsStream("db/torrentmanager.sqlite"),
                dbfile
            );
            logger.info("db file was inited!");
        } else {
            logger.info("db file read ok");
        }


        // 数据库表机构更新
        updateDatabase(configService.getCurrent().getVersion());
        // 更新为当前版本号
        configService.getCurrent().setVersion(appConfig.getVersion());
        configService.update(new UpdateWrapper<Config>().lambda().set(Config::getVersion, appConfig.getVersion()).eq(Config::getTag, "system"));


        // 初始化下载客服务器
        List<Client> clients = clientService.list();
        clients.stream().forEach(client -> BtClients.put(client));
    }

    private void updateDatabase(String preVersion) {
        updateDatabase_0_1_1(preVersion);
//        updateDatabase_0_1_2(preVersion);
    }

    private void updateDatabase_0_1_2(String preVersion) {
        if (versionOutdate(preVersion, "0.1.2")) {
            logger.info("数据库结构更新！(v0.1.2)");
            // todo update database for 0.1.2 changes
        }
    }

    private void updateDatabase_0_1_1(String preVersion) {
        if (versionOutdate(preVersion, "0.1.1")) {
            logger.info("数据库结构更新！(v0.1.1)");
            jdbcTemplate.execute("ALTER TABLE 'torrent' ADD 'torrent_file' TEXT");
        }
    }

    private boolean versionOutdate(String preVersion, String curVersion) {
        int[] pre = splitVersion(preVersion);
        int[] cur = splitVersion(curVersion);
        for (int i = 0; i < 3; i++) {
            if (pre[i] == cur[i]) continue;
            return pre[i] < cur[i];
        }
        return false;
    }

    private int[] splitVersion(String v) {
        int[] version = new int[3];
        if (!StringUtils.hasText(v)) {
            String[] tmp1 = v.split("-");
            String[] tmp2 = tmp1[0].split("\\.");
            for (int i = 0; i < tmp2.length; i++) {
                version[i] = Integer.parseInt(tmp2[i]);
            }
        }
        return version;
    }

//    public static void main(String[] args) {
////        int[] version1 = new ApplicationRunnerImpl().splitVersion("0.1.0");
////        int[] version = new ApplicationRunnerImpl().splitVersion("0.1.1");
////        System.out.println(Arrays.toString(version1));
////        System.out.println(Arrays.toString(version));
//        System.out.println(new ApplicationRunnerImpl().versionOutdate("0.1.1-dev", "0.1.1"));
//    }
}
